#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
@desc: .

@Project ：kuberCloudTest
@File ：compute.py
@Author ：admin
@Date ：2024/3/21 14:20 
"""
from kuberCloudTest.cloud_resources.specifications.utils import specUtils, PhysicalAllocationPolicy, DiskIOps, \
    DiskBandwidth
from kuberCloudTest.cloud_resources.urls import CloudResourcesUrls
from kuberCloudTest.common.constant import OFFSET, LIMIT, AsyncType
from kuberCloudTest.common.utils import _getDetail, _getOperationType
from kuberCloudTest.exception import KuberCloudException


def getComputeSpec(accessToken, specId=None, **kwargs):
    """
    获取计算规格
    :param specId: 计算规格uuid
    :param accessToken: access token
    :param kwargs: limit:
                   offset:
                   keyword: xxx
    :return:
    """
    spec_utils = specUtils(accessToken=accessToken)
    content = spec_utils.cloud_http_request.get(CloudResourcesUrls.getComputeSpec.value,
                                                {
                                                    'offset': kwargs.get('offset', OFFSET),
                                                    'limit': kwargs.get('limit', LIMIT),
                                                    'keyword': kwargs.get('keyword', '')
                                                })
    if specId:
        total = content.get('total', 0)
        content = spec_utils.cloud_http_request.get(
            CloudResourcesUrls.getComputeSpec.value, {'limit': total, 'offset': OFFSET})
        content = _getDetail(content, specId, 'specid')
    return content


def createComputeSpec(accessToken, name, cpuNum: int, memoryNum: int, memoryUnit,
                      diskIOps: DiskIOps,
                      physicalAllocationPolicy: PhysicalAllocationPolicy,
                      diskBandwidth: DiskBandwidth,
                      **kwargs):
    """
    创建计算规格
    :param accessToken: access token
    :param name: 计算规格名称
    :param cpuNum: cpu个数
    :param memoryNum: 内存数值 (512~524288 M; 1~512 G)
    :param memoryUnit: 内存单位 M|G
    :param diskIOps: 读写速度
    :param physicalAllocationPolicy:物理机分配策略
                        1: 运行云主机数量最少
                        2: CPU使用率最低
                        3: 内存使用率最低
                        4: 运行云主机最大数量
    :param diskBandwidth: 带宽
    :param kwargs: remark: 计算规格描述
    :return:
    """

    def _checkMemoryUnit(unit):
        if unit not in ('M', 'G'):
            raise KuberCloudException('params error', 'memoryUnit error')

    operationType = 1201
    data = _getOperationType(operationType, AsyncType.SYNC.value)

    _checkMemoryUnit(memoryUnit)
    data['name'] = name
    data['cpunum'] = cpuNum
    data['memorynum'] = memoryNum
    data['memoryunit'] = memoryUnit

    data['allocatorstrategy'] = physicalAllocationPolicy.allocationPolicy
    data['strategymodel'] = physicalAllocationPolicy.strategicMode
    data['maxvmcount'] = physicalAllocationPolicy.maxVmCount

    data['diskiopstype'] = diskIOps.diskIOpsType
    data['disktotaliops'] = diskIOps.diskTotalIOps
    data['diskreadiops'] = diskIOps.diskReadIOps
    data['diskwriteiops'] = diskIOps.diskWriteIOps

    data['bandwidthtype'] = diskBandwidth.diskBandwidthType
    data['diskbandwidthnum'] = diskBandwidth.diskBandwidthNum
    data['diskbandwidthunit'] = diskBandwidth.diskBandwidthUnit
    data['volumereadbandwidthnum'] = diskBandwidth.diskReadBandwidthNum
    data['volumereadbandwidthunit'] = diskBandwidth.diskReadBandwidthUnit
    data['volumewritebandwidthnum'] = diskBandwidth.diskWriteBandwidthNum
    data['volumewritebandwidthunit'] = diskBandwidth.diskWriteBandwidthUnit
    data['networkupbandwidthnum'] = diskBandwidth.networkUpBandwidthNum
    data['networkupbandwidthunit'] = diskBandwidth.networkUpBandwidthUnit
    data['networkoutbandwidthnum'] = diskBandwidth.networkOutBandwidthNum
    data['networkoutbandwidthunit'] = diskBandwidth.networkOutBandwidthUnit

    data['remark'] = kwargs['remark'] if 'remark' in kwargs.keys() else ''

    specUtils(accessToken=accessToken).cloud_http_request.post(CloudResourcesUrls.createComputeSpec.value, data=data)


def updateComputeSpec(accessToken, specId, **kwargs):
    """
    更新计算规格
    :param accessToken: access token
    :param specId: 计算规格uuid
    :param kwargs: name: 计算规格名称
                   remark: 计算规格描述
                   allocationPolicy: 物理机分配策略
                        1: 运行云主机数量最少
                        2: CPU使用率最低
                        3: 内存使用率最低
                        4: 运行云主机最大数量
                   strategicMode: 策略模式 (allocationPolicy=2|3, strategicMode必填)
                        1：强制
                        2：非强制
                   maxVmCount: 最大vm数(allocationPolicy=4, maxVmCount必填)
    :return:
    """
    computeSpec = getComputeSpec(accessToken=accessToken, specId=specId).get('obj', None)
    if not computeSpec:
        raise KuberCloudException('params error', 'computeSpec [{}] not exist'.format(specId))

    operationType = 1202
    data = _getOperationType(operationType, AsyncType.SYNC.value)
    data['specid'] = specId
    data['name'] = kwargs.get('name', computeSpec['name'])
    data['allocatorstrategy'] = kwargs.get('allocationPolicy', computeSpec['allocationPolicy'])
    if data['allocatorstrategy'] == 2 or data['allocatorstrategy'] == 3:
        data['strategymodel'] = kwargs.get('strategicMode', computeSpec['strategymodel'])
    else:
        data['maxvmcount'] = kwargs.get('maxVmCount', computeSpec['maxvmcount'])
    data['remark'] = kwargs.get('remark', computeSpec['remark'])

    return specUtils(accessToken=accessToken).cloud_http_request.post(CloudResourcesUrls.updateComputeSpec.value,
                                                                      data=data)


def startComputeSpec(accessToken, computeSpecIds):
    """
    启用计算规格uuid
    :param accessToken: access token
    :param computeSpecIds: 计算规格uuid (多个使用英文逗号分割)
    :return:
    """
    operationType = 1204
    data = _getOperationType(operationType, AsyncType.SYNC.value)
    data['ids'] = computeSpecIds
    return specUtils(accessToken=accessToken).cloud_http_request.post(
        CloudResourcesUrls.startComputeSpec.value, data=data)


def stopComputeSpec(accessToken, computeSpecIds):
    """
    停用计算规格
    :param accessToken: access token
    :param computeSpecIds: 计算规格uuid (多个使用英文逗号分割)
    :return:
    """
    operationType = 1205
    data = _getOperationType(operationType, AsyncType.SYNC.value)
    data['ids'] = computeSpecIds
    return specUtils(accessToken=accessToken).cloud_http_request.post(
        CloudResourcesUrls.stopComputeSpec.value, data=data)


def deleteComputeSpec(accessToken, computeSpecIds):
    """
    删除计算规格
    :param accessToken: access token
    :param computeSpecIds: 计算规格uuid (多个使用英文逗号分割)
    :return:
    """
    operationType = 1203
    data = _getOperationType(operationType, AsyncType.SYNC.value)
    data['ids'] = computeSpecIds
    return specUtils(accessToken=accessToken).cloud_http_request.post(
        CloudResourcesUrls.deleteComputeSpec.value, data=data)


def globalShareComputeSpec(accessToken, computeSpecIds):
    """
    计算规格全局共享
    :param accessToken: access token
    :param computeSpecIds: 计算规格uuid (多个使用英文逗号分割)
    :return:
    """
    operationType = 1206
    data = _getOperationType(operationType, AsyncType.SYNC.value)
    data['ids'] = computeSpecIds
    return specUtils(accessToken=accessToken).cloud_http_request.post(
        CloudResourcesUrls.globalShareComputeSpec.value, data=data)


def globalRecallComputeSpec(accessToken, computeSpecIds):
    """
    计算规格全局召回
    :param accessToken: access token
    :param computeSpecIds: 计算规格uuid (多个使用英文逗号分割)
    :return:
    """
    operationType = 1207
    data = _getOperationType(operationType, AsyncType.SYNC.value)
    data['ids'] = computeSpecIds
    return specUtils(accessToken=accessToken).cloud_http_request.post(
        CloudResourcesUrls.globalRecallComputeSpec.value, data=data)
